package com.fendaren.util;

import com.fendaren.exceptions.GraceException;
import com.fendaren.grace.result.ResponseStatusEnum;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Encoder;

import javax.crypto.SecretKey;
import java.util.Date;

@Component
@Slf4j
public class JWTUtils {

    @Autowired
    private JWTProperties jwtProperties;

    public String createJWTWithPrefix(String body, Long expireTimes, String prefix) {
        if (expireTimes == null) {
            GraceException.display(ResponseStatusEnum.SYSTEM_NO_EXPIRE_ERROR);
        }
        return prefix + "@" + dealJWT(body, expireTimes);
    }

    public String createJWTWithPrefix(String body, String prefix) {
        return prefix + "@" + dealJWT(body, null);
    }

    public String createJWT(String body) {
        return dealJWT(body, null);
    }

    public String createJWT(String body, Long expireTimes) {
        if (expireTimes == null) {
            GraceException.display(ResponseStatusEnum.SYSTEM_NO_EXPIRE_ERROR);
        }
        return dealJWT(body, expireTimes);
    }

    public String dealJWT(String body, Long expireTimes) {
        String userKey = jwtProperties.getKey();
        String base64 = new BASE64Encoder().encode(userKey.getBytes());
        SecretKey secretKey = Keys.hmacShaKeyFor(base64.getBytes());
        String jwt = "";
        if (expireTimes != null) {
            jwt = generatorJWT(body, expireTimes, secretKey);
        } else {
            jwt = generatorJWT(body, secretKey);
        }
        log.info("jwt:{}", jwt);
        return jwt;
    }

    public String generatorJWT(String body, SecretKey secretKey) {
        String jwtToken = Jwts.builder()
                .setSubject(body)
                .signWith(secretKey)
                .compact();
        return jwtToken;

    }

    public String generatorJWT(String body, long expireTimes, SecretKey secretKey) {
        Date expireDate = new Date(System.currentTimeMillis() + expireTimes);
        String jwtToken = Jwts.builder()
                .setSubject(body)
                .signWith(secretKey)
                .setExpiration(expireDate)
                .compact();
        return jwtToken;

    }

    public String checkJWT(String pendingJWT) {
        String userKey = jwtProperties.getKey();
        String base64 = new BASE64Encoder().encode(userKey.getBytes());
        System.out.println(base64);

        SecretKey secretKey = Keys.hmacShaKeyFor(base64.getBytes());
        JwtParser jwtParser = Jwts.parserBuilder().setSigningKey(secretKey).build();
        Jws<Claims> claimsJws = jwtParser.parseClaimsJws(pendingJWT);
        String body = claimsJws.getBody().getSubject();
        System.out.println(body);
        return body;
    }
}
